// 图表工具类
export class ChartUtils {
  // 绘制折线图
  static drawLineChart(canvas, data, options = {}) {
    const ctx = canvas.getContext('2d')
    const { width, height } = canvas
    const {
      colors = ['#1890ff', '#52c41a', '#faad14'],
      showGrid = true,
      showLabels = true,
      padding = { top: 20, right: 20, bottom: 40, left: 50 }
    } = options

    // 清空画布
    ctx.clearRect(0, 0, width, height)

    // 计算绘图区域
    const chartWidth = width - padding.left - padding.right
    const chartHeight = height - padding.top - padding.bottom

    // 绘制网格
    if (showGrid) {
      ctx.strokeStyle = '#e9ecef'
      ctx.lineWidth = 1
      
      // 水平网格线
      for (let i = 0; i <= 5; i++) {
        const y = padding.top + (chartHeight / 5) * i
        ctx.beginPath()
        ctx.moveTo(padding.left, y)
        ctx.lineTo(width - padding.right, y)
        ctx.stroke()
      }
      
      // 垂直网格线
      for (let i = 0; i <= data.labels.length - 1; i++) {
        const x = padding.left + (chartWidth / (data.labels.length - 1)) * i
        ctx.beginPath()
        ctx.moveTo(x, padding.top)
        ctx.lineTo(x, height - padding.bottom)
        ctx.stroke()
      }
    }

    // 计算数据范围
    const allValues = data.datasets.flatMap(dataset => dataset.data)
    const maxValue = Math.max(...allValues)
    const minValue = Math.min(...allValues, 0)
    const valueRange = maxValue - minValue

    // 绘制数据线
    data.datasets.forEach((dataset, datasetIndex) => {
      const color = colors[datasetIndex % colors.length]
      
      ctx.strokeStyle = color
      ctx.lineWidth = 2
      ctx.beginPath()

      dataset.data.forEach((value, index) => {
        const x = padding.left + (chartWidth / (data.labels.length - 1)) * index
        const y = height - padding.bottom - ((value - minValue) / valueRange) * chartHeight

        if (index === 0) {
          ctx.moveTo(x, y)
        } else {
          ctx.lineTo(x, y)
        }

        // 绘制数据点
        ctx.fillStyle = color
        ctx.beginPath()
        ctx.arc(x, y, 3, 0, 2 * Math.PI)
        ctx.fill()
      })

      ctx.stroke()
    })

    // 绘制标签
    if (showLabels) {
      ctx.fillStyle = '#666'
      ctx.font = '12px Arial'
      ctx.textAlign = 'center'
      
      data.labels.forEach((label, index) => {
        const x = padding.left + (chartWidth / (data.labels.length - 1)) * index
        ctx.fillText(label, x, height - 10)
      })

      // 绘制Y轴标签
      ctx.textAlign = 'right'
      for (let i = 0; i <= 5; i++) {
        const value = minValue + (valueRange / 5) * (5 - i)
        const y = padding.top + (chartHeight / 5) * i
        ctx.fillText(Math.round(value), padding.left - 10, y + 4)
      }
    }

    // 绘制图例
    if (data.datasets.length > 1) {
      let legendX = width - 150
      data.datasets.forEach((dataset, index) => {
        const color = colors[index % colors.length]
        const y = 20 + index * 20

        ctx.fillStyle = color
        ctx.fillRect(legendX, y, 15, 3)
        
        ctx.fillStyle = '#333'
        ctx.font = '12px Arial'
        ctx.textAlign = 'left'
        ctx.fillText(dataset.label || `数据${index + 1}`, legendX + 20, y + 8)
      })
    }
  }

  // 绘制饼图
  static drawPieChart(canvas, data, options = {}) {
    const ctx = canvas.getContext('2d')
    const { width, height } = canvas
    const {
      colors = ['#1890ff', '#52c41a', '#faad14', '#f5222d', '#722ed1'],
      showLabels = true,
      showPercentages = true
    } = options

    // 清空画布
    ctx.clearRect(0, 0, width, height)

    const centerX = width / 2
    const centerY = height / 2
    const radius = Math.min(centerX, centerY) - 60

    // 计算总值
    const total = data.reduce((sum, item) => sum + item.value, 0)

    let currentAngle = -Math.PI / 2

    data.forEach((item, index) => {
      const sliceAngle = (item.value / total) * 2 * Math.PI
      const color = colors[index % colors.length]

      // 绘制扇形
      ctx.fillStyle = color
      ctx.beginPath()
      ctx.moveTo(centerX, centerY)
      ctx.arc(centerX, centerY, radius, currentAngle, currentAngle + sliceAngle)
      ctx.closePath()
      ctx.fill()

      // 绘制边框
      ctx.strokeStyle = '#fff'
      ctx.lineWidth = 2
      ctx.stroke()

      // 绘制标签
      if (showLabels) {
        const labelAngle = currentAngle + sliceAngle / 2
        const labelRadius = radius + 30
        const labelX = centerX + Math.cos(labelAngle) * labelRadius
        const labelY = centerY + Math.sin(labelAngle) * labelRadius

        ctx.fillStyle = '#333'
        ctx.font = '12px Arial'
        ctx.textAlign = 'center'
        
        const percentage = showPercentages ? ` (${((item.value / total) * 100).toFixed(1)}%)` : ''
        ctx.fillText(`${item.label}${percentage}`, labelX, labelY)
      }

      currentAngle += sliceAngle
    })
  }

  // 绘制柱状图
  static drawBarChart(canvas, data, options = {}) {
    const ctx = canvas.getContext('2d')
    const { width, height } = canvas
    const {
      colors = ['#1890ff', '#52c41a', '#faad14'],
      showGrid = true,
      showLabels = true,
      padding = { top: 20, right: 20, bottom: 40, left: 50 }
    } = options

    // 清空画布
    ctx.clearRect(0, 0, width, height)

    // 计算绘图区域
    const chartWidth = width - padding.left - padding.right
    const chartHeight = height - padding.top - padding.bottom

    // 绘制网格
    if (showGrid) {
      ctx.strokeStyle = '#e9ecef'
      ctx.lineWidth = 1
      
      for (let i = 0; i <= 5; i++) {
        const y = padding.top + (chartHeight / 5) * i
        ctx.beginPath()
        ctx.moveTo(padding.left, y)
        ctx.lineTo(width - padding.right, y)
        ctx.stroke()
      }
    }

    // 计算数据范围
    const maxValue = Math.max(...data.map(item => item.value))
    const barWidth = chartWidth / data.length * 0.6
    const barSpacing = chartWidth / data.length * 0.4

    // 绘制柱状图
    data.forEach((item, index) => {
      const barHeight = (item.value / maxValue) * chartHeight
      const x = padding.left + index * (chartWidth / data.length) + barSpacing / 2
      const y = height - padding.bottom - barHeight

      const color = colors[index % colors.length]
      ctx.fillStyle = color
      ctx.fillRect(x, y, barWidth, barHeight)

      // 绘制数值标签
      ctx.fillStyle = '#333'
      ctx.font = '12px Arial'
      ctx.textAlign = 'center'
      ctx.fillText(item.value, x + barWidth / 2, y - 5)
    })

    // 绘制X轴标签
    if (showLabels) {
      ctx.fillStyle = '#666'
      ctx.font = '12px Arial'
      ctx.textAlign = 'center'
      
      data.forEach((item, index) => {
        const x = padding.left + index * (chartWidth / data.length) + (chartWidth / data.length) / 2
        ctx.fillText(item.label, x, height - 10)
      })

      // 绘制Y轴标签
      ctx.textAlign = 'right'
      for (let i = 0; i <= 5; i++) {
        const value = (maxValue / 5) * (5 - i)
        const y = padding.top + (chartHeight / 5) * i
        ctx.fillText(Math.round(value), padding.left - 10, y + 4)
      }
    }
  }

  // 绘制热力图
  static drawHeatmap(canvas, data, options = {}) {
    const ctx = canvas.getContext('2d')
    const { width, height } = canvas
    const {
      colorScale = ['#f0f9ff', '#0ea5e9', '#0369a1'],
      showLabels = true,
      padding = { top: 40, right: 20, bottom: 40, left: 60 }
    } = options

    // 清空画布
    ctx.clearRect(0, 0, width, height)

    const cellWidth = (width - padding.left - padding.right) / data.xLabels.length
    const cellHeight = (height - padding.top - padding.bottom) / data.yLabels.length

    // 计算数值范围
    const allValues = data.values.flat()
    const minValue = Math.min(...allValues)
    const maxValue = Math.max(...allValues)
    const valueRange = maxValue - minValue

    // 绘制热力图格子
    data.values.forEach((row, rowIndex) => {
      row.forEach((value, colIndex) => {
        const x = padding.left + colIndex * cellWidth
        const y = padding.top + rowIndex * cellHeight

        // 计算颜色强度
        const intensity = valueRange > 0 ? (value - minValue) / valueRange : 0
        const color = this.interpolateColor(colorScale, intensity)

        ctx.fillStyle = color
        ctx.fillRect(x, y, cellWidth, cellHeight)

        // 绘制边框
        ctx.strokeStyle = '#fff'
        ctx.lineWidth = 1
        ctx.strokeRect(x, y, cellWidth, cellHeight)

        // 绘制数值
        if (showLabels) {
          ctx.fillStyle = intensity > 0.5 ? '#fff' : '#333'
          ctx.font = '10px Arial'
          ctx.textAlign = 'center'
          ctx.fillText(value, x + cellWidth / 2, y + cellHeight / 2 + 3)
        }
      })
    })

    // 绘制坐标轴标签
    if (showLabels) {
      ctx.fillStyle = '#666'
      ctx.font = '12px Arial'
      
      // X轴标签
      ctx.textAlign = 'center'
      data.xLabels.forEach((label, index) => {
        const x = padding.left + index * cellWidth + cellWidth / 2
        ctx.fillText(label, x, height - 10)
      })

      // Y轴标签
      ctx.textAlign = 'right'
      data.yLabels.forEach((label, index) => {
        const y = padding.top + index * cellHeight + cellHeight / 2 + 4
        ctx.fillText(label, padding.left - 10, y)
      })
    }
  }

  // 颜色插值
  static interpolateColor(colors, intensity) {
    if (intensity <= 0) return colors[0]
    if (intensity >= 1) return colors[colors.length - 1]

    const scaledIntensity = intensity * (colors.length - 1)
    const lowerIndex = Math.floor(scaledIntensity)
    const upperIndex = Math.ceil(scaledIntensity)
    const localIntensity = scaledIntensity - lowerIndex

    if (lowerIndex === upperIndex) return colors[lowerIndex]

    // 简单的RGB插值
    const lowerColor = this.hexToRgb(colors[lowerIndex])
    const upperColor = this.hexToRgb(colors[upperIndex])

    const r = Math.round(lowerColor.r + (upperColor.r - lowerColor.r) * localIntensity)
    const g = Math.round(lowerColor.g + (upperColor.g - lowerColor.g) * localIntensity)
    const b = Math.round(lowerColor.b + (upperColor.b - lowerColor.b) * localIntensity)

    return `rgb(${r}, ${g}, ${b})`
  }

  // 十六进制颜色转RGB
  static hexToRgb(hex) {
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
    return result ? {
      r: parseInt(result[1], 16),
      g: parseInt(result[2], 16),
      b: parseInt(result[3], 16)
    } : null
  }
}

// 数据导出工具
export class ExportUtils {
  // 导出CSV
  static exportToCSV(data, filename = 'export.csv') {
    const csvContent = this.arrayToCSV(data)
    this.downloadFile(csvContent, filename, 'text/csv;charset=utf-8;')
  }

  // 导出Excel (简单版本，使用CSV格式)
  static exportToExcel(data, filename = 'export.xlsx') {
    const csvContent = this.arrayToCSV(data)
    this.downloadFile(csvContent, filename.replace('.xlsx', '.csv'), 'text/csv;charset=utf-8;')
  }

  // 导出JSON
  static exportToJSON(data, filename = 'export.json') {
    const jsonContent = JSON.stringify(data, null, 2)
    this.downloadFile(jsonContent, filename, 'application/json;charset=utf-8;')
  }

  // 数组转CSV
  static arrayToCSV(data) {
    if (!data || data.length === 0) return ''
    
    // 获取表头
    const headers = Object.keys(data[0])
    const csvRows = [headers.join(',')]
    
    // 添加数据行
    data.forEach(row => {
      const values = headers.map(header => {
        const value = row[header]
        // 处理包含逗号或引号的值
        if (typeof value === 'string' && (value.includes(',') || value.includes('"'))) {
          return `"${value.replace(/"/g, '""')}"`
        }
        return value
      })
      csvRows.push(values.join(','))
    })
    
    return csvRows.join('\n')
  }

  // 下载文件
  static downloadFile(content, filename, mimeType) {
    const blob = new Blob(['\ufeff' + content], { type: mimeType })
    const link = document.createElement('a')
    const url = URL.createObjectURL(blob)
    
    link.setAttribute('href', url)
    link.setAttribute('download', filename)
    link.style.visibility = 'hidden'
    
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    
    URL.revokeObjectURL(url)
  }

  // 生成报表PDF (使用浏览器打印功能)
  static printReport(title = '报表') {
    const printWindow = window.open('', '_blank')
    const printContent = document.querySelector('.report-container').outerHTML
    
    printWindow.document.write(`
      <!DOCTYPE html>
      <html>
        <head>
          <title>${title}</title>
          <style>
            body { font-family: Arial, sans-serif; margin: 20px; }
            .report-container { max-width: none; }
            .filter-section, .report-tabs, .table-actions, .pagination { display: none; }
            .report-table { font-size: 10px; }
            .report-table th, .report-table td { padding: 4px; }
            @media print {
              body { margin: 0; }
              .no-print { display: none; }
            }
          </style>
        </head>
        <body>
          <h1>${title}</h1>
          <p>生成时间: ${new Date().toLocaleString()}</p>
          ${printContent}
        </body>
      </html>
    `)
    
    printWindow.document.close()
    printWindow.focus()
    
    setTimeout(() => {
      printWindow.print()
      printWindow.close()
    }, 500)
  }
}